<?php
namespace App\Admin\Controllers\Products;

use App\Admin\Actions\Products\MixSku\ImportMixSku;
use App\Admin\Actions\Products\MixSku\DisableItem;
use App\Admin\Actions\Products\MixSku\EnableItem;
use App\Admin\Extensions\Grid\Tool\Export;
use App\Models\Basics\Supplier;
use App\Models\Inventory\InventoryCn;
use App\Models\Inventory\Timely;
use App\Models\Product\ProductClassify;
use App\Models\Product\ProductMixSku;
use App\Models\Product\ProductPackageMaterial;
use App\Models\Product\ProductPpt;
use App\Models\Product\ProductQuality;
use App\Models\Product\ProductSku;
use App\Models\Product\ProductSkuClassify;
use App\Models\Product\ProductSkuColor;
use App\Util\RExcel;
use App\Util\SerialSkuNo;
use App\Util\User;
use Encore\Admin\Admin as SAdmin;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Grid;
use Encore\Admin\Form;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Request;

class MixSkuController extends AdminController{

    protected $title = '组合产品管理';

    protected function _style()
    {
        return <<<STYLE
.column-__actions__ {
    white-space: nowrap;
}
STYLE;
    }

    protected function grid()
    {
        SAdmin::style($this->_style());
        $grid = new Grid(new ProductMixSku());
        $grid->model()->newQuery()
            ->where('is_mix',1)
            ->orderBy('id', 'DESC');
        $grid->model()->collection(function (Collection $collection){
            foreach($collection as $item) {
                $re = ProductMixSku::getMixSkuPuCycleAndPuPrice($item->mix_rule);
                $item->supplier_price = numberFormat($re['supplier_price']);
                $item->unit_price = numberFormat($re['unit_price']);
                $item->self_price = numberFormat(round($re['unit_price'] - $re['supplier_price'],3));

                $item->purchase_cycle = numberFormat($re['purchase_cycle']);
                $item->instant = Timely::getInstant($item->id);
                $item->muser_id = User::getUsernameById($item->muser_id);
                $item->cuser_id = User::getUsernameById($item->cuser_id);
            }
            return $collection;
        });
        $grid->column('id','ID')->filter();
        $grid->column('psku_code','SKU');
        $grid->column('part_number','PartNo.');
        $grid->column('is_sales','是否在售')->bool()->filter(ProductSku::$_isSales);
        $grid->column('psku_cn','名称')->style('max-width:200px');
        $grid->column('classify.season','季节性')->using(ProductClassify::$_season);
        $grid->column('classify.title','品类')->style('max-width:200px');
        $grid->column('classify.model_no','ModelNo');
        $grid->column('img','图片')->display(function ($value){
            return ProductSku::getMainImage($value,60,60);
        });
        $grid->column('supplier_price','供应商单价');
        $grid->column('self_price','自购单价');
        $grid->column('unit_price','总采购单价');
        $grid->column('purchase_cycle','周期');
        $grid->column('instant','库存');
        $grid->column('psku_status','产品状态')->using(ProductSku::$_pSkuStatus)->filter(ProductSku::$_pSkuStatus);
        $grid->column('muser_id','负责人');
        $grid->column('cuser_id','创建人');
        $grid->column('status','启用')->bool([1 => true, 2 => false]);
        $grid->column('is_brand','是否为品牌产品')->bool([ProductSku::BRAND_YES => true, ProductSku::BRAND_NO => false]);

        $grid->disableExport();
        $grid->tools(function (Grid\Tools $tools){
            $tools->append(new Export('products/mix-sku-download'));
        });
        $grid->actions(function (Grid\Displayers\Actions $actions) {
            $actions->disableDelete();
            if(!Admin::user()->can('mix-sku.edit')){
                $actions->disableEdit();
            }
        });
        if(Admin::user()->can('mix-sku.edit')){
            $grid->batchActions(function (Grid\Tools\BatchActions $batch) {
                $batch->disableDelete();
                $batch->add(new DisableItem());
                $batch->add(new EnableItem());
            });
            $grid->tools(function (Grid\Tools $tools) {
                $tools->append(new ImportMixSku());
            });
        }else{
            $grid->disableBatchActions();
            $grid->disableCreateButton();
        }
        $grid->fixHeader();
        $grid->filter(function($filter){
            $filter->column(1/3, function ($filter){
                $filter->where(function ($query) {
                    $query->where('psku_code', 'like', "%{$this->input}%")
                        ->orWhere('psku_cn', 'like', "%{$this->input}%")
                        ->orWhere('part_number', 'like', "%{$this->input}%");
                }, '查询','sku8')->placeholder('模糊查询SKU，名称，PartNo.');
                $filter->equal('muser_id','负责人')->select(User::getMUserOptions(FALSE));
            });
            $filter->column(1/3, function ($filter) {
                $filter->equal('classify.season', '季节性')->select(ProductClassify::$_season);
                $filter->equal('classify_id', '品类')->select(ProductClassify::options());
            });
            $filter->column(1/3, function ($filter){
                $filter->in('status', '启用')->checkbox(ProductSku::$_status);
                $filter->equal('cuser_id','创建人')->select(User::getCUserOptions());
            });
        });

        return $grid;
    }

    protected function detail($id)
    {
        $ps = ProductMixSku::query()->findOrFail($id);
        $skuPuCycleAndPuPrice = ProductMixSku::getMixSkuPuCycleAndPuPrice($ps->mix_rule);
        $relatedSkuInfo = ProductMixSku::relatedSkuInfo($ps->mix_rule);
        $relatedSkuSuppliers = ProductMixSku::relatedSkuSuppliers($ps->mix_rule);
        $ppt = ProductPpt::query()->where('classify_id',$ps->classify_id)->value('ppt');
        $qualities = ProductQuality::query()->where('classify_id',$ps->classify_id)->value('qualities');
        $packages = ProductPackageMaterial::query()->where('classify_id',$ps->classify_id)->value('packages');
        return view('products.mix-sku.detail.index',
            compact('id','ps','skuPuCycleAndPuPrice','relatedSkuInfo','relatedSkuSuppliers','ppt','qualities','packages'));
    }

    protected function form()
    {
        $form = new Form(new ProductSku());
        $form->tab('基本信息', function (Form $form) {
            $form->hidden('id');
            if ($form->isCreating()) {
                $form->hidden('psku_code');
                $form->hidden('part_number');
            }else{
                $form->display('psku_code', 'SKU');
                $form->display('part_number','PartNo.');
            }
            $form->text('psku_cn','产品名称')->rules('required');
            $form->select('classify_id','品类')->options(ProductClassify::options())->rules('required');
            $form->select('psku_status','产品状态')->options(ProductSku::$_pSkuStatus)->default(2)->rules('required');
            $form->select('muser_id','产品负责人')->options(User::getMUserOptions(FALSE))->rules('required');
            $form->switch('status', '启用')->states(statusSwitch())->default('1');
            $form->hidden('cuser_id')->value(Admin::user()->id);
            $form->hidden('m_psku_id');
            $form->hidden('m_num');

            if ($form->isCreating()) {
                $form->radio('is_brand', '是否为品牌产品')
                    ->options(ProductSku::$_brand)
                    ->when(ProductSku::BRAND_NO, function (Form $form1) {
                        //非品牌产品 (sku亚马逊规则)(AM00001...)
                    })
                    ->when(ProductSku::BRAND_YES, function (Form $form2){
                        //品牌产品 (sku品牌规则)(SLP0024SSBK2P...)
                        $form2->select('classify_code','品类名（三位字母）')
                            ->options(ProductSkuClassify::options())->pattern('[A-Z]{3}')->rules('required')
                            ->help('品类英文三位大写字母组合，例：睡垫(Sleeping Pad），可标识为：SLP');

                        $form2->text('item_number','款号（两位数字）')->pattern('[0-9]{2}')->rules('required')
                            ->help('款号使用00-99内不同数字标识该品类下不同的产品款式，注意同样造型下的不同性能/功能用不同的款号区分开，例：三合一人造棉睡袋用01，三合一羽绒睡袋用02');

                        $form2->text('year_number','年份（两位数字）')->pattern('[0-9]{2}')->rules('required')
                            ->help('产品上市年份的后两位数字，例：产品预计为2024年上市，则使用24标识年份');

                        $form2->select('season_code','季节（SS/AW/FS）')
                            ->options(['SS'=>'SS-夏季', 'AW'=>'AW-冬季', 'FS'=>'FS-其他'])->pattern('[A-Z]{2}')->rules('required')
                            ->help('产品的适用季节，SS(Spring&Summer)春夏季，AW(Autumn&Winter)秋冬季，FS-无季节区分');

                        $form2->select('color_code','颜色（两位字母）')
                            ->options(ProductSkuColor::options())->pattern('[A-Z]{2}')->rules('required')
                            ->help('颜色英文两位大写字母组合，例：黑色(Black)，可标识为：BK');

                        $form2->text('spec_code','规格（两位数字/字母）')->pattern('[0-9A-Z]{2}')->rules('required')
                            ->help('尺寸根据不同产品的不同需求，使用两位数字/字母组合来标识产品的关键尺寸，方便快速从命名规则中知道产品的关键尺寸。 例如：
                        <br>帐篷 2P（2人）4P（四人），<br>睡袋 RG（Regular 常规）LN（Long 加长），<br>睡垫 RG（Regular 常规）WD（Wide 加宽），
                        <br>穿戴类 3S(XXS) 2S(XS) 1S(S) 1M(M) 1L(L) 2L(XL) 3L(XXL)，
                        <br>单一尺寸（均码）FF');
                    })
                    ->default(ProductSku::BRAND_NO)->required(); //默认值：非品牌产品
            }else{
                $form->radio('is_brand', '是否为品牌产品')->options(ProductSku::$_brand)->disable();
            }
        });

        $form->tab('组合规则', function (Form $form) {
            if($form->isCreating()){
                $form->hidden('is_mix')->value(1);
                $form->text('mix_rule', '组合规则')->rules('required',['required'=>'请填写组合规则'])->help('请使用英文输入法编写组合规则，格式为：SKU-NUM(使用逗号隔开)');
                $form->radio('mix_mode','组合模式')->options(ProductSku::$_mixMode)->default(2)->help('关联产品入库后的组合模式');
            }else{
                $form->radio('is_mix','组合类型')
                    ->options(ProductSku::$_isMix)
                    ->when(0, function (Form $form) {
                        $form->select('product_supplier.supplier_id','供应商')
                            ->options(Supplier::options(false))->rules('required')
                            ->help('若更新为普通产品请务必选择默认供应商！');
                        $form->number('product_supplier.moq','最小起订量')->default(0)->min(0);
                        $form->decimal('product_supplier.supplier_price','供应商单价')->options(['digits'=>3])->attribute(['maxlength'=>8])->rules('required|gt:0');
                        $form->decimal('product_supplier.unit_price','总采购单价')->options(['digits'=>3])->attribute(['maxlength'=>8])->rules('required|gt:0');
                        $form->number('product_supplier.purchase_cycle','采购周期(天)')->default(1)->min(1)->rules('required');
                        $form->radio('product_supplier.status','默认')->options([1=>'默认'])->default(1);
                    })->when(1, function (Form $form) {
                        $form->text('mix_rule', '组合规则')->rules('required',['required'=>'请填写组合规则'])
                            ->help('请使用英文输入法编写组合规则，格式为：SKU-NUM(使用逗号隔开)，更新规则请确保该产品已无库存');
                        $form->radio('mix_mode','组合模式')->options(ProductSku::$_mixMode)->default(1)->help('关联产品入库后的组合模式');
                    })
                    ->help('若更新组合类型请确保该产品已无库存，此操作不可逆请谨慎操作');
            }
        });
        $form->tab('产品描述', function (Form $form) {
            $form->textarea('psku_describe', '产品描述')->rows(10);
        });
        $form->tab('产品图片', function (Form $form) {
            $form->image('img','主图')->removable()->thumbnail('small', $width = 300, $height = 300);
            $form->multipleImage('image.pics','其他')->removable()->sortable();
        });
        $form->tab('包材信息', function (Form $form) {
            //采购有权限，仓库无权限
            $form->decimal('packing.pack_long','包装长度(CM)')->options(['digits'=>3])->attribute(['maxlength'=>8]);
            $form->decimal('packing.pack_wide','包装宽度(CM)')->options(['digits'=>3])->attribute(['maxlength'=>8]);
            $form->decimal('packing.pack_high','包装高度(CM)')->options(['digits'=>3])->attribute(['maxlength'=>8]);
            $form->decimal('packing.ship_weight','产品发货重量(KG)')->options(['digits'=>3])->attribute(['maxlength'=>8]);
        });

        $form->saving(function (Form $form) {
            if($form->isCreating()){
                if ($form->is_brand == ProductSku::BRAND_YES) {
                    //(生成sku编码) 品牌产品编码
                    $code = $form->classify_code.$form->item_number.$form->year_number.$form->season_code.$form->color_code.$form->spec_code;
                    $partNumber = $code;

                }elseif ($form->is_brand == ProductSku::BRAND_NO) {
                    //(生成sku编码) 非品牌产品编码
                    $code = SerialSkuNo::init();
                    $partNumber = str_replace('AM','PN',$form->psku_code);
                }else{
                    admin_error('ERROR', '编码异常');
                }
                $existsSku = ProductSku::query()->where('psku_code', $code)->exists();
                if ($existsSku) {
                    admin_error('ERROR', 'SKU编码已存在，请查看SKU命名规则，匹配添加');
                    return back()->withInput();
                }
                $form->psku_code = $code;
                $form->part_number = $partNumber;

                $flag = ProductMixSku::checkMixRule($form->mix_rule);
                if(!$flag){
                    admin_error('组合规则有误','关联产品必须为普通产品');
                    return back()->withInput();
                }
                $arr = ProductMixSku::getMpSku($form->mix_rule);
                $form->m_psku_id = $arr['m_psku_id'];
                $form->m_num = $arr['m_num'];
            }else{
                if(!($form->input('img') == '_file_del_') && ($form->is_mix == 0 || $form->model()->mix_rule != $form->mix_rule)){
                    //验证库存
                    if(InventoryCn::existTransit($form->model()->id)){
                        admin_error('在途库存未清0','在途库存未清0勿修改规则');
                        return back()->withInput();
                    }
                    if($form->is_mix == 0){
                        $form->m_psku_id = null;
                        $form->m_num = null;
                    }
                    if($form->model()->mix_rule != $form->mix_rule){
                        $flag = ProductMixSku::checkMixRule($form->mix_rule);
                        if(!$flag){
                            admin_error('组合规则有误','关联产品必须为普通产品');
                            return back()->withInput();
                        }
                        $arr = ProductMixSku::getMpSku($form->mix_rule);
                        $form->m_psku_id = $arr['m_psku_id'];
                        $form->m_num = $arr['m_num'];
                    }
                }
            }
        });

        $form->tools(function (Form\Tools $tools) {
            $tools->disableDelete();
        });
        
        return $form;
    }

    public function download(){
        $request = Request::input();
        $query = $this->_initQuery($request);
        $this->_exeDownload($query);
    }

    private function _initQuery($filters){
        $query = ProductSku::query()->where('is_mix',1)->orderBy('id', 'DESC');
        foreach ($filters as $key => $_filter){
            if($key == 'sku8'){
                $query->where(function ($query) use($_filter){
                    $query->where('psku_code', 'like', "%{$_filter}%")
                        ->orWhere('psku_cn', 'like', "%{$_filter}%")
                        ->orWhere('part_number', 'like', "%{$_filter}%");
                });
            }
            if($key == 'classify'){
                $query->whereHas('classify', function ($query) use($_filter){
                    $query->where('season', $_filter['season']);
                });
            }
            if(in_array($key,['status'])){
                $query->whereIn($key,$_filter);
            }
            if(in_array($key,['muser_id','classify_id','cuser_id'])){
                $query->where($key,$_filter);
            }
        }
        return $query;
    }

    private function _exeDownload($query){
        $head = ['SKU','PartNo.','组合','组合规则','是否在售','名称','季节性','品类','ModelNo','供应商单价','自购单价','总采购单价','采购周期','库存','产品状态','负责人','创建人','创建时间','状态','是否为品牌产品'];
        RExcel::exportCsv('组合产品',function () use ($head, $query) {
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, $head);
            $query->chunk(1000, function ($re) use ($fp){
                $data = self::getDownloadData($re);
                foreach ($data as $item) {
                    fputcsv($fp, $item);
                }
            });
        });
    }

    public static function getDownloadData($res)
    {
        $seller = [];
        foreach ($res as $model){
            if(!array_key_exists($model->muser_id,$seller)){
                $seller[$model->muser_id] = User::getUsernameById($model->muser_id);
            }
            if(!array_key_exists($model->cuser_id,$seller)){
                $seller[$model->cuser_id] = User::getUsernameById($model->cuser_id);
            }
            $data = ProductMixSku::getMixSkuPuCycleAndPuPrice($model->mix_rule);
            $selfPrice = round($data['unit_price'] - $data['supplier_price'],3);
            $temp = [
                $model->psku_code,
                $model->part_number,
                '组合',
                $model->mix_rule,
                ProductSku::$_isSales[$model->is_sales],
                $model->psku_cn,
                ProductClassify::$_season[$model->classify->season ?? 3],
                $model->classify->title ?? '',
                $model->classify->model_no ?? '',
                numberFormat($data['supplier_price']),
                numberFormat($selfPrice),
                numberFormat($data['unit_price']),
                $data['purchase_cycle'],
                Timely::getInstant($model->id),
                ProductSku::$_pSkuStatus[$model->psku_status],
                $seller[$model->muser_id],
                $seller[$model->cuser_id],
                $model->created_at,
                ProductSku::$_status[$model->status],
                ProductSku::$_brand[$model->is_brand],
            ];
            yield $temp;
        }
    }
}
